package com.qire.manhua.model.viewModel.impl;

import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.View;
import android.widget.TextView;

import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.qire.antsbinder.viewModel.ViewModelFactory;
import com.qire.antsrouter.AntsRouter;
import com.qire.antsrouter.card.RoomCard;
import com.qire.common.SummerApp;
import com.qire.common.GlideApp;
import com.qire.common.basic.DateUtil;
import com.qire.common.basic.ObjectUtil;
import com.qire.common.basic.StringUtil;
import com.qire.common.constant.Navigation;
import com.qire.common.function.Consumer;
import com.qire.common.model.entity.UserEntity;
import com.qire.common.support.AbsBringDialogViewModel;
import com.qire.common.utils.ToastHelper;
import com.qire.common.widget.adapter.pager.SimpleFragmentPagerAdapter;
import com.qire.common.widget.adapter.pager.SimpleFragmentPagerAdapter.FragmentWrapper;
import com.qire.common.widget.snackbar.Prompt;
import com.qire.manhua.activity.ComicDetailActivity;
import com.qire.manhua.controller.ComicDetailController;
import com.qire.manhua.databinding.ActivityComicDetailBinding;
import com.qire.manhua.dialog.VipFreeTipsDialog;
import com.qire.manhua.dialog.VipFreeTipsDialog.DialogType;
import com.qire.manhua.model.entity.ComicBookEntity;
import com.qire.manhua.model.entity.ComicBookEntity.LockInfo;
import com.qire.manhua.model.entity.ComicBookEntity.DirectoryInfo;
import com.qire.manhua.model.entity.ShareInfo;
import com.qire.manhua.model.enumeration.FreeType;
import com.qire.manhua.model.viewModel.IComicDetailViewModel;
import com.qire.manhua.dal.service.ComicDetailService;
import com.qire.manhua.view.filter.BlurBuilder;
import com.qire.manhua.view.filter.FastBlur;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;
import androidx.fragment.app.Fragment;

public class ComicDetailViewModel extends AbsBringDialogViewModel<IComicDetailViewModel> {

    /** 漫画详情页数据服务 */
    private final ComicDetailService comicDetailService = new ComicDetailService(this);
    /** 详情页简介 */
    private ComicDetailIntroductionViewModel introductionViewModel;
    /** 详情页目录 */
    private ComicDetailDirectoryViewModel directoryViewModel;


    /** 展示的漫画实体 */
    private ComicBookEntity comicBookEntity;

    /** 分享信息 */
    private ShareInfo shareInfo;

    /** 最近阅读章节索引 */
    private int historyReadChapterIndex = -1;

    /** 免费限期时间 */
    private Date freeLimitTime;

    //region    #附加管理 begin
    /** 附加属性绑定 */
    public void onAddition(ComicDetailActivity activity) {

        introductionViewModel = ViewModelFactory.crate(activity, ComicDetailIntroductionViewModel.class);
        directoryViewModel = ViewModelFactory.crate(activity, ComicDetailDirectoryViewModel.class);
        directoryViewModel.setComicDetail(this);

        final Fragment introductionFragment = AntsRouter.ROUTER.<RoomCard>buildCard(Navigation.Fragment.ComicDetailIntroductionFragment)
                .withData("viewModel", introductionViewModel).get();

        final Fragment directoryFragment = AntsRouter.ROUTER.<RoomCard>buildCard(Navigation.Fragment.ComicDetailDirectoryFragment)
                .withData("viewModel", directoryViewModel).get();

        SimpleFragmentPagerAdapter comicDetailPagerAdapter = new SimpleFragmentPagerAdapter(activity.getSupportFragmentManager(), new FragmentWrapper[] {
                new FragmentWrapper("详情", introductionFragment),
                new FragmentWrapper("选集", directoryFragment)
        });

        ActivityComicDetailBinding viewDataBinder = activity.viewDataBinder();
        viewDataBinder.comicDetailViewPager.setAdapter(comicDetailPagerAdapter);
        viewDataBinder.comicDetailTabLayout.setViewPager(viewDataBinder.comicDetailViewPager);
        TextView tab = (TextView) viewDataBinder.comicDetailTabLayout.getTabAt(0);
        tab.setTypeface(Typeface.DEFAULT_BOLD);

    }

    /**
     * 清理函数，在Activity退出时，ViewModel生命周期到期会被回收，调用该事件，
     * 页面由于切换、横竖屏转换、内存回收等情况并不会影响到ViewModel的生命周期。
     */
    @Override
    protected void onCleared() {
        super.onCleared();
        this.comicBookEntity = null;
    }
    //endregion #附加管理 end

    //region    #业务数据相关 begin
    /** 加载漫画详情、简介、相关推荐等信息。 */
    public void loadDetailInfo(int comicBookId) {
        comicDetailService.fetchComicDetailData(comicBookId);
    }

    /** 加载漫画目录信息，每次加载都会重新清空目录在刷新。 */
    public void loadDirectoryInfo() {
        comicDetailService.fetchComicDirectoryInfo(comicBookEntity.id);
    }

    /** 提供给接服务器接口返回的历史阅读章节索引 */
    public void setHistoryReadChapterIndex(int historyReadChapterIndex) {
        this.historyReadChapterIndex = historyReadChapterIndex;
    }

    /** 由于章节可能随着本地操作而改变，消费服务器历史后应该置为无效状态，不在取服务器的历史。 */
    public void loadHistoryReadChapter() {
        if(historyReadChapterIndex > 0) {
            DirectoryInfo readDirectoryInfo = ObjectUtil.safeRun(comicBookEntity, comic -> comic.findDirectoryInfo(historyReadChapterIndex));
            if (ObjectUtil.nonNull(readDirectoryInfo)) {
                comicBookEntity.chaptersReading(readDirectoryInfo.chapterId);
            }
            historyReadChapterIndex = -1;
        }
        refreshReadChapterInfo();
    }

    /** 通过广告解锁指定章节 */
    public void unlockChapterByAd(int chapterId) {
        comicDetailService.unlockChapterByAd(comicBookEntity.id, chapterId);
    }

    /** 通过购买解锁指定章节 */
    public void unlockChapterByBuy(int chapterId, String chapterPrice, String paymentType) {
        int comicId = comicBookEntity.id;
        int autoPay = UserEntity.self.isAutoPay() ? 1 : 0;
        comicDetailService.unlockChapterByBuy(comicId, chapterId, chapterPrice, paymentType, autoPay);
    }

    /** 加载漫画详情信息 */
    public void loadComicBookEntity(ComicBookEntity comicBookEntity) {
        this.comicBookEntity = comicBookEntity;
        introductionViewModel.loadComicBookEntity(comicBookEntity);

        put("bookName", comicBookEntity.bookName);
        refreshFavoriteBtnUI();
    }

    /** 当前查看的漫画实体 */
    public ComicBookEntity comicBookEntity() {
        return comicBookEntity;
    }

    /** 是否收藏，如果是收藏状态则会切换为取消收藏，反之亦然 */
    public void whetherToFavorites() {
        if(ObjectUtil.isNull(comicBookEntity)) {
            ToastHelper.showToast("漫画书数据有误");
            return;
        }
        comicDetailService.whetherJoinMyBookshelf(comicBookEntity);
    }

    /** 刷新收藏结果 */
    public void refreshFavorite(String resultMsg, String takeMsg) {
        if(StringUtil.notContains(resultMsg, "失败")) {
            comicBookEntity.whetherCollect(StringUtil.notContains(resultMsg, "取消"));
        }

        ToastHelper.showSnackBar(resultMsg, Prompt.SUCCESS);
        if(StringUtil.notEmpty(takeMsg)) {
            ToastHelper.showSnackBar(takeMsg, Prompt.SUCCESS);
        }

        refreshFavoriteBtnUI();
    }

    /** 设置分享信息 */
    public void setShareInfo(ShareInfo shareInfo) {
        this.shareInfo = shareInfo;
    }

    public ShareInfo shareInfo() {
        return shareInfo;
    }
    //endregion #业务数据相关 end

    //region    #子页相关数据 begin

    /**
     * 调用简介数据加载相关操作，作用将 introductionViewModel 以回调方式暴露给外界使用
     * @param loadAction 加载数据的行为
     */
    public void callIntroDataAction(Consumer<ComicDetailIntroductionViewModel> loadAction) {
        if(loadAction != null && introductionViewModel != null) {
            loadAction.accept(introductionViewModel);
        }
    }

    /**
     * 调用目录数据加载相关操作，作用将 directoryViewModel 以回调方式暴露给外界使用
     * @param loadAction 加载数据的行为
     */
    public void callDirectoryDataAction(Consumer<ComicDetailDirectoryViewModel> loadAction) {
        if(loadAction != null && directoryViewModel != null) {
            loadAction.accept(directoryViewModel);
        }
    }

    //endregion #子页相关数据 end

    //region    #UI修改 begin
    /** 跳转指定的2级选项卡页 */
    public void gotoTabPage(int pageNo) {
        set("pageNo", pageNo);
    }

    /** 设置封面层透明度 */
    public void setCoverLayerAlpha(float alpha) {
        set("coverLayerAlpha", alpha);
    }

    /** 刷新收藏按钮UI状态 */
    public void refreshFavoriteBtnUI() {
        put("whetherCollection", ObjectUtil.safeRun(comicBookEntity, comic -> comic.whetherCollect(), false));
    }


    /**
     * 设置模糊背景和书籍封面图
     * @param coverLayerImgPath 封面路径
     */
    public void setCoverImgPath(String coverLayerImgPath) {
        if(StringUtil.notEmpty(coverLayerImgPath)) {
            GlideApp.with(SummerApp.summerApp()).asBitmap().load(coverLayerImgPath).into(bitmapCustomTarget);
        }
    }
    private CustomTarget<Bitmap> bitmapCustomTarget = new CustomTarget<Bitmap>() {
        @Override
        public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
            boolean lessThan_JELLY_BEAN_MR1 = Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1;
            Bitmap coverImg = resource;
            Bitmap coverLayerImg = lessThan_JELLY_BEAN_MR1 ? FastBlur.doBlur(coverImg, 70, true) : BlurBuilder.blur(SummerApp.summerApp(), coverImg);
            put("coverImg", coverImg);
            put("coverLayerImg", coverLayerImg);
        }
        @Override
        public void onLoadCleared(@Nullable Drawable placeholder) {}
    };

    /** 设置漫画封面标签标签 */
    public void setComicBookTags(String[] comicBookTags) {
        put("comicBookTags", comicBookTags);
    }

    /** 设置底部开始阅读按钮文本 */
    public void setReadChapterBtnText(String readChapterBtnText) {
        put("readChapterBtnText", readChapterBtnText);
    }

    /** 加载免费相关信息 */
    public void loadFreeInfo(String freeReadTimeLimit, String freeReadTipsText) {
        freeReadTimeLimit = StringUtil.replace(freeReadTimeLimit, "0000-00-00 23:59:59", 0, 19);
        if(DateUtil.yMdHms.valid(freeReadTimeLimit)) {
            this.freeLimitTime = DateUtil.yMdHms.parse(freeReadTimeLimit);
        }

        refreshFreeInfo(freeLimitTime, freeReadTipsText);
    }
    /** 刷新显示免费相关UI */
    private void refreshFreeInfo(Date freeLimitTime, String freeReadTipsText) {
        if(StringUtil.isEmpty(freeReadTipsText)) {
            put("freeReadTipsTextVisible", View.GONE);
            return;
        }

        put("freeReadTipsText", freeReadTipsText);

        LockInfo lockInfo = comicBookEntity.lockInfo();

        boolean checkFreeTimeOut = freeLimitTime == null || freeLimitTime.getTime() <= System.currentTimeMillis();

        String freeLimitTimeTips =  checkFreeTimeOut ? ""
                // 计算时差
                : DateUtil.calcTimeDiff(new Date().getTime(), freeLimitTime.getTime())
                // 格式化，指定格式化的标准，前缀，后缀
                .formatBy(TimeUnit.MILLISECONDS::toDays, "限免剩余", "天");
        put("freeLimitTimeTips", freeLimitTimeTips);

        if(ObjectUtil.nonNull(lockInfo)) {
            switch (lockInfo.bookFreeType) {
                case VipFree :
                    put("freeReadTipsTextVisible", View.VISIBLE);
                    break;
                case VipLimitTimeFree :
                    put("freeReadTipsTextVisible", checkFreeTimeOut ? View.GONE : View.VISIBLE);
                    break;
            }
        }
    }

    /** 刷新当前阅读章节信息 */
    public void refreshReadChapterInfo() {
        String readChapterFullName;
        String readChapterBtnText;

        if(comicBookEntity == null) {
            readChapterFullName = "";
            readChapterBtnText = "免费阅读";
        } else {
            DirectoryInfo readDirectoryInfo = comicBookEntity.defReadingDirectoryInfo();
            readChapterFullName = ObjectUtil.isNull(readDirectoryInfo) ? "" : readDirectoryInfo.chapterName;
            readChapterBtnText = readDirectoryInfo.serialId != 1 ? "继续阅读" : "免费阅读";
        }

        put("readChapterFullName", readChapterFullName);
        setReadChapterBtnText(readChapterBtnText);
    }
    //endregion #UI修改 end

    //region    #Dialog控制 begin

    private int freeChapterCount = -1;
    private String feeStartChapter = "";

    /**
     * 设置免费弹窗提示信息
     * @param freeChapterCount 免费章节统计数
     * @param feeStartChapter 免费起始章节名
     */
    public void setFreeChapterCount(int freeChapterCount, String feeStartChapter) {
        this.freeChapterCount = freeChapterCount;
        this.feeStartChapter = feeStartChapter;
    }

    /**
     * 显示Vip免费提示弹窗
     * @param controller 事件控制器
     */
    public void showVipFreeTipsDialog(ComicDetailController controller) {
        if(comicBookEntity == null || comicBookEntity.lockInfo() == null) {
            return;
        }

        FreeType comicBookFreeType = comicBookEntity.lockInfo().bookFreeType;

        DialogType  dialogType = (comicBookFreeType == FreeType.VipFree && freeChapterCount == 0) ? DialogType.All : DialogType.Part;

        VipFreeTipsDialog.build(dialogType)
                .setComicDetailController(controller)
                .setVipFreeTipsDialogViewModel(new VipFreeTipsDialogViewModel())
                .show();
    }

    /**
     * Vip免费提示弹窗ViewModel
     */
    public class VipFreeTipsDialogViewModel extends BaseObservable {
        @Bindable
        public CharSequence getFreeChapterBeginTips() {
            FreeType comicBookFreeType = comicBookEntity.lockInfo().bookFreeType;
            if(comicBookFreeType == FreeType.VipFree && freeChapterCount == 0) {
                return "《" + comicBookEntity.bookName + "》";
            } else if((comicBookFreeType == FreeType.VipFree && freeChapterCount > 0)){
                // 章节免费不限时
                return "从“" + feeStartChapter + "”开始";
            } else if(comicBookFreeType == FreeType.VipLimitTimeFree) {
                // 会员专属 限时
                return freeChapterCount > 0 ? "从“" + feeStartChapter + "”开始" : "《" + comicBookEntity.bookName + "》";
            }
            return "";
        }

        @Bindable
        public CharSequence getFreeChapterCountTips() {
            FreeType comicBookFreeType = comicBookEntity.lockInfo().bookFreeType;
            if(comicBookFreeType == FreeType.VipFree && freeChapterCount == 0) {
                return "会员可免费阅读此本漫画";
            } else if((comicBookFreeType == FreeType.VipFree && freeChapterCount > 0)) {
                return "免费阅读" + freeChapterCount + "话";
            } else if(comicBookFreeType == FreeType.VipLimitTimeFree) {
                return freeChapterCount > 0 ? "免费阅读" + freeChapterCount + "话" : "会员可免费阅读此本漫画";
            }
            return "";
        }

        @Bindable
        public CharSequence getFreeValidity() {
            FreeType comicBookFreeType = comicBookEntity.lockInfo().bookFreeType;
            if(comicBookFreeType == FreeType.VipLimitTimeFree) {
                return "限免结束时间：" + DateUtil.yMdHms.format(freeLimitTime);
            }
            return "";
        }
    }

    //endregion #Dialog控制 end

}
